﻿// ConsoleApplication.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// 本测试程序显示结果使用opencv
//
#include <stdio.h>
#include<string.h>
#include "imageUtil.h"
#include "ioUtil.h"

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp> 
using namespace cv;

int convertYuv420ToMat(void* dst, byte* pYUV420, int width, int height) {
	if (!pYUV420) {
		return 1;
	}
	IplImage* yuvimage, * rgbimg, * yimg, * uimg, * vimg, * uuimg, * vvimg;

	unsigned short nWidth = width;
	unsigned short nHeight = height;
	rgbimg = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 3);
	yuvimage = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 3);

	yimg = cvCreateImageHeader(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 1);
	uimg = cvCreateImageHeader(cvSize(nWidth / 2, nHeight / 2), IPL_DEPTH_8U, 1);
	vimg = cvCreateImageHeader(cvSize(nWidth / 2, nHeight / 2), IPL_DEPTH_8U, 1);

	uuimg = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 1);
	vvimg = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 1);
	cvSetData(yimg, pYUV420, nWidth);
	cvSetData(uimg, pYUV420 + (nWidth * nHeight), nWidth / 2);
	cvSetData(vimg, pYUV420 + (int)((float)(nWidth * nHeight) * 1.25f), nWidth / 2);
	cvResize(uimg, uuimg, CV_INTER_LINEAR);
	cvResize(vimg, vvimg, CV_INTER_LINEAR);

	cvMerge(yimg, uuimg, vvimg, NULL, yuvimage);
	cvCvtColor(yuvimage, rgbimg, CV_YCrCb2RGB);

	cvReleaseImage(&uuimg);
	cvReleaseImage(&vvimg);
	cvReleaseImageHeader(&yimg);
	cvReleaseImageHeader(&uimg);
	cvReleaseImageHeader(&vimg);

	cvReleaseImage(&yuvimage);

	//dst = Mat(*rgbimg,int(1));
	Mat* pDst = (Mat*)dst;
	(*pDst) = cvarrToMat(rgbimg, true);
	//rgbimg->
	cvReleaseImage(&rgbimg);
	return 0;
}
int convertYuv422ToMat(void* dst, byte* pYUV422, int width, int height) {
	int code = 0;
	//int yuv422Size = (width * height * 2);
	int yuv420Size = ((width * height * 3) / 2);
	byte* pYUV420 = (byte*)malloc(yuv420Size);
	//memset(pYUV420, 0, yuv420Size);
	yuv422p_to_yuvI420(pYUV420, pYUV422, width, height);
	//saveAllBytes("d:\\test_420.yuv", pYUV420, yuv420Size);
	code = convertYuv420ToMat(dst, pYUV420, width, height);
	free(pYUV420);
	pYUV420 = 0;
	return code;
}
void showImage(byte* src,nInt width,nInt height,const char* name) {
	Mat m1;
	convertYuv422ToMat(&m1, src, width, height);
	imshow(name, m1);
}
int main()
{
	const int w = 480;
	const int h = 320;

	int len;
	byte* buf = 0, * dstBuf = 0;
	readAllBytes("test422_480-320.yuv", &buf, &len);
	dstBuf = (byte*)malloc(len);

	byte yMin, yMax;

	showImage(buf, w, h, "原图");

	//色阶调整
	yuv422p_levels(dstBuf, buf, w, h, 80, 128, 20,NFalse);
	showImage(dstBuf, w, h, "色阶调整");
	//对比度调整
	yuv422p_convert_to(dstBuf, buf, w, h, 1.5, 5);
	showImage(dstBuf, w, h, "对比度调整");
	//高斯模糊
	yuv422p_perform_gaussian_filter(dstBuf, buf, w, h, 0.5);
	showImage(dstBuf, w, h, "高斯模糊");
	//中值滤波
	 yuv422p_perform_median_filter(dstBuf, buf, w, h);
	 showImage(dstBuf, w, h, "中值滤波");
	//自动色阶
	yuv422p_levels_extend(dstBuf, buf, w, h, 20, &yMin, &yMax);
	showImage(dstBuf, w, h, "自动色阶");
	//灰度处理
	yuv422p_gray(dstBuf, buf, w, h);
	showImage(dstBuf, w, h, "灰度");
	//全局阈值化
	yuv422p_threshold(dstBuf, buf, w, h, 128);
	showImage(dstBuf, w, h, "全局阈值化");
	//迭代阈值化
	yuv422p_threshold_iteration(dstBuf, buf, w, h, 128);
	 showImage(dstBuf, w, h, "迭代阈值化");
	//局部阈值化
	yuv422_adaptive_threshold(dstBuf, buf, w, h, 0.25, 20);
	showImage(dstBuf, w, h, "局部阈值化");

	waitKey(0);
	free(buf);
	free(dstBuf);
}